Miyamasuを支える技術というかUnityEditorロックインな知識
概要
Miyamasuを作った時に発覚したいろんな新常識を列挙していく。
Miyamasu
https://github.com/sassembla/Miyamasu
PlayerのTheadとUnityEditor.EditorApplication.updateの話
Unityの制作環境には大きく2つ、MainThreadへのアクセスポイントがあり、
1つはPlayerが動いているときのUpdateとかあのへん。MonoBehaviourが動いているContext。
もう一つは、UnityEditor.EditorApplication.updateが動いているContext。
この2つのContextは、根本的には一つのThread(= MainThread)にアクセスしていて、その動作に差異は「ほぼ」ない。
具体例として、
UnityのMainThreadでしか動かないよ~的なメソッドは、そのほぼ全てが UnityEditor.EditorApplication.update でも動かすことができる。
Play中でないと絶対に動かない処理がある
UnityEditor.EditorApplication.update と、MonoBehaviourは等価っぽい、、、のだけれど、
次のメソッドは、Play中でないと動作が完了しないことがわかっている。
・LoadAssetAsync
・ConfigurationBuilder.Instance
LoadAssetAsync
DLしたAssetBundleを非同期で読み出す処理なんだけど、全然完了しない。
ConfigurationBuilder.Instance
課金機構の設定用のインスタンスを返す処理なんだけど、これまた全然完了しない。
これらは、UnityEditorがIsPlaying = trueでないと動作しない。
が、
裏を返せば、UnityEditorがIsPlaying = true でさえあれば、
例えば、UnityEditor.EditorApplication.updateからでも動作する。
考察としては、
・これらのメソッド中には、Play中かどうかをみて動くような処理が実装されている
という感じ。
もしくはバグ。だってUnityWebRequestとか同期版のLoadAssetは動く。
この2つのメソッド以外にもあるかも。(特に探せてない
ちなみに実機上でテストを動かす場合には全然問題ない。
なぜNUnitを使わないかについて、、、うん、、、、
Unity、NUnitを使ってテストを書くことができるんだけど、テスト実行単位で一つのMainThreadだけが動く状態で、
MainThread主体のコンテキストで動いてしまい、MainThreadを空転させるような動作ができない。
もうちょっというと、例えばStartCoroutineして、その処理の終了を待つ、みたいなことができない。
MainThreadで動いてて、MainThreadで動かすような処理を待ちたい、で、待つ = ロックしちゃう = 非同期で完了を待ちたい処理もロックしちゃう。
ので、非同期的な処理を待つことができない。
ので、非同期テストができない。
ご丁寧なことに、NUnit中には、上記のUnityEditor.updateも動かない。
はい解散。